//
//  KoiSheet.swift
//  TestDependency
//
//  Created by 纪洪文 on 26.03.25.
//

import SwiftUI

extension View {
    func koiSheet<Content: View>(isPresented: Binding<Bool>, onDismiss: (() -> Void)? = nil, @ViewBuilder content: () -> Content) -> some View {
        modifier(KoiSheetModifier(isPresented: isPresented, onDismiss: onDismiss, content))
    }
    
    func koiSheet<Item: Identifiable, Content: View>(item: Binding<Item?>, onDismiss: (() -> Void)? = nil, @ViewBuilder content: (Item) -> Content) -> some View {
        modifier(KoiSheetItemModifier(item: item, onDismiss: onDismiss, content))
    }
}

struct KoiSheetModifier<SheetContent: View> : ViewModifier {
    
    @State private var subHeight: CGFloat = 0
    @Binding var isPresented: Bool
    var onDismiss: (() -> Void)? = nil
    var sheetContent: SheetContent
    
    init(isPresented: Binding<Bool>, onDismiss: (() -> Void)? = nil, @ViewBuilder _ content: () -> SheetContent) {
        _isPresented = isPresented
        self.onDismiss = onDismiss
        sheetContent = content()
    }
    
    func body(content: Content) -> some View {
        content
            .background(
                sheetContent.background(
                GeometryReader { proxy in
                  Color.clear
                    .task(id: proxy.size.height) {
                      subHeight = proxy.size.height
                    }
                }
                ).hidden()
            )
            .presentationDetents([.height(subHeight)])
            .sheet(isPresented: $isPresented, onDismiss: onDismiss) {
                sheetContent.presentationDetents([.height(subHeight)])
            }.id(subHeight)
    }
}

struct KoiSheetItemModifier<Item: Identifiable, SheetContent: View> : ViewModifier {
    
    @State private var subHeight: CGFloat = 0
    @Binding var item: Item?
    var onDismiss: (() -> Void)? = nil
    var sheetContent: SheetContent?
    
    init(item: Binding<Item?>, onDismiss: (() -> Void)? = nil, @ViewBuilder _ content: (Item) -> SheetContent) {
        _item = item
        let value = item.wrappedValue
        if value != nil {
            sheetContent = content(item.wrappedValue!)
        }
        self.onDismiss = onDismiss
    }
    
    func body(content: Content) -> some View {
        if sheetContent == nil {
            content
        } else {
            content
                .background(
                    sheetContent.background(
                    GeometryReader { proxy in
                      Color.clear
                        .task(id: proxy.size.height) {
                          subHeight = proxy.size.height
                        }
                    }
                    ).hidden()
                )
                .presentationDetents([.height(subHeight)])
                .sheet(item: $item, onDismiss: onDismiss) { _ in
                    sheetContent.presentationDetents([.height(subHeight)])
                }.id(subHeight)
        }
    }
}
